#ifndef HISTOGRAM_MATRIX3D_H
#define HISTOGRAM_MATRIX3D_H

#include <string>
#include "histogram.hxx"
#include "ptr.hxx"
#include <vector>

class Matrix3D
{
public:
    enum CudaStrategy {
        SIMPLE = 0,
        OPTIMIZED = 1
    };

    enum Derivative{
    DX = 0, DY = 1, DZ = 2
    };

    Matrix3D(int xCount = 32, int yCount = 32, int zCount = 32, Ptr<short> data = 0, short minThreshold = -32768, short maxThreshold = 32767)
        :_xCount(xCount),_yCount(yCount),_zCount(zCount),_data(data), _minThreshold(minThreshold),_maxThreshold(maxThreshold){}

    Histogram histogram(int warpCount, Histogram::Type type = Histogram::DESTRIBUTION, Matrix3D::CudaStrategy strategy = Matrix3D::OPTIMIZED);
    Matrix3D sobel(Matrix3D::Derivative type);
    void transform(std::vector<int> classes);
    void smooth();
    void store(char* filePath);

private:
    inline int modelSize(){return _xCount * _yCount * _zCount;}

    int _xCount;
    int _yCount;
    int _zCount;

    short _minThreshold;
    short _maxThreshold;

    Ptr<short> _data;
};

namespace Matrix
{
    Matrix3D parse(std::string path);
    Matrix3D generateUniform(int x, int y, int z);
};

#endif
